package cn.scs.client;

import cn.scs.common.Config;
import cn.scs.common.MetaOpCode;


import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class MetaServerClient {

    private static final String META_SERVRE_HOST = Config.META_SERVRE_HOST; // 元数据服务器的主机名
    private static final int METADATA_SERVER_PORT = Config.META_SERVRE_PORT; // 元数据服务器的端口号
    private Connection connection;  // -HUADD 去掉了final

    public MetaServerClient() throws IOException {
        connection = new Connection(META_SERVRE_HOST, METADATA_SERVER_PORT);
    }
//    public static void main(String[] args) {
//        MetaServerClient metaServerClient;
//
//        try {
//            metaServerClient = new MetaServerClient();
//            // 发送请求并接收响应
//            List<String> files = metaServerClient.listFilesName("/");
//            System.out.println("files:"+files);
//            metaServerClient.createFile("/MetaData");
//            metaServerClient.createFile("/Metadata/test");
//
//            files = metaServerClient.listFilesName("/");
//            System.out.println("files:"+files);
//
//            //test--deleteFile
//            metaServerClient.deleteFile("/MetaData");
//            files = metaServerClient.listFilesName("/");
//            System.out.println("files:"+files);
//
//
//            metaServerClient.connection.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }
    // 更新连接
    public void updateConnection() throws IOException {
        connection.close(); // 先关闭老Connection
        connection = new Connection(META_SERVRE_HOST, METADATA_SERVER_PORT);
    }

    public List<String> listFile(String cur_dir) {
        List<String> fl = new ArrayList<>();
        try {
            MetaOpCode.LIST_FILE.write(connection.getOut()); //
            connection.flush();
            connection.writeUTF(cur_dir); // 客户端发送路径
            connection.flush();
//            System.out.println("调用函数了！！");
            int size =  connection.readInt();
            if (size == -1){
//                System.out.println("path not found.");
            }else if (size == 0){
//                System.out.println("directory is empty.");
                fl.add("empty directory");
            }else {
                System.out.println("list size:" + size);
                for(int i = 0;i<size;i++){
                    fl.add(connection.readUTF());
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return fl;
    }

    public String heartBeat(String nodeName) {
        try {
            MetaOpCode.HEART_BEAT.write(connection.getOut()); //
            connection.flush();
            connection.writeUTF(nodeName); // 读取客户端发送路径
            connection.flush();
            int code = connection.readInt();
            //读取元数据服务器返回的心跳处理信息
            return connection.readUTF();

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String createFile(String path) {
        try {
            MetaOpCode.CREATE_FILE.write(connection.getOut()); //向服务器发送 操作码code
            connection.flush();
            connection.writeUTF(path); // 向服务器发送 路径
            connection.writeUTF(Config.USER); // 向服务器发送 用户
            // 是否为目录
            connection.writeBoolean(false);
            connection.flush();

            int code = connection.readInt();
            if (code == -1) {return null;}   //-1表示失败
            return connection.readUTF();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // 向MetaServer申请追加对应File的block分块
    public String applyBlock(String path, String lastUUID) {
        // path: 对应的元数据path
        // lastUUID: 上一个块的 UUID 用于验证拼接
        try {
            MetaOpCode.APPLY_BLOCK.write(connection.getOut());
            connection.flush();
            connection.writeUTF(path);
            connection.writeUTF(Config.USER);
            connection.writeUTF(lastUUID);
            connection.flush();
            // 接收返回值
            int code = connection.readInt();
            return connection.readUTF();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // 获取下载
    public List<String> downloadFile(String path) {
        try {
            MetaOpCode.DOWNLOAD_FILE.write(connection.getOut());
            connection.flush();
            connection.writeUTF(path);
            connection.writeUTF(Config.USER);
            connection.flush();
            List<String> locations = getLocations(connection);
            int code = connection.readInt();
            String info = connection.readUTF();
            if (code == 0){ return locations; }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public List<String> deleteFile(String path) {
        try {
            MetaOpCode.DEL_FILE.write(connection.getOut()); //向服务器发送 操作码code
            connection.flush();
            connection.writeUTF(path); // 向服务器发送 路径
            connection.writeUTF(Config.USER); // 向服务器发送 用户
//            connection.writeBoolean(false); // 是否为目录
            connection.flush();
            List<String> locations = getLocations(connection);
            int code = connection.readInt();
            String info = connection.readUTF();
            if (code == 0){ return locations; }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // 地址locations获取
    public List<String> getLocations(Connection connection) throws IOException {
        List<String> locations = new ArrayList<>();
        int size = connection.readInt();    // 列表长度
        for (int i=0; i<size; i++) {
            locations.add(connection.readUTF());
        }
        return locations;
    }

    public Boolean renameFile(String path,String newName) {
        try {
            MetaOpCode.RENAME_FILE.write(connection.getOut());//向服务器发送 操作码code
            connection.flush();
            connection.writeUTF(path); // 向服务器发送 文件路径
            connection.writeUTF(newName); // 向服务器发送 新文件名
            connection.flush();
            int code = connection.readInt();
            return code != -1;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // DFS客户端退出
    public boolean DFS_Client_exit() {
        try {
            MetaOpCode.DFS_CLIENT_EXIT.write(connection.getOut());
            connection.flush();
            connection.writeUTF(Config.USER);   // 写入退出用户
            connection.flush();
            int code = connection.readInt();
            String info = connection.readUTF();
            if (code == 0) {return true;}   // 成功激活MetaServer端退出钩子函数
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void close() throws IOException {
        this.connection.close();
    }

    // 假设还有其他辅助方法的实现...
}

